Skip to main content

Astro

Astro is a site generator tool that focuses on site speed. It supports static site generation (SSG), server side rendering (SSR), and a hybrid between the two (as of Astro 2.0).

It's main feature is Islands where it ships no javascript by default, and only shipping javascript when it's actually necessary. You can also use your components from pretty much any other framework!

Using Astro

Their documentation is great. I recommend using the searchbar on their docs site. Nevertheless, I have included some items here.

Astro NPM Commands

  • npm create astro@latest to create Astro project
  • npm run dev uses Vite to start Astro dev server
  • npm run build builds production site to ./dist/
  • npm run preview serves ./dist/ to test deployment

Folder Structure

  • Everything happens in the src folder, it is processed by astro
    • Inside is the pages folder. Everything in here is automatically a route
    • index.astro is the homepage, like webreaper.dev
      • Ex. if you have about.astro it is at webreaper.dev/about
  • public is at base root of server. Astro will not touch it. This is a good place to put images for example
  • astro.config.mjs is config setup for Astro

Routing

Anything under the pages directory is automatically a route.

pages/index.astro is at the base route (/)

pages/about.astro is at /about

pages/blog/index.astro is at /blog

Layouts (Templates)

You use "slots" to create layouts in astro. These are conventionally stored as src/layouts. In your layout .astro file you put <slot />. Whenever you wrap and astro page in the template, whatever you wrap will go inside the <slot> tag.

You can also have named slots (for multiple slots in the same layout) and fallback content. See info about that in the astro docs.

exampleTemplate.astro
---
const {title} = Astro.props;
---

<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot>
"Default if nothing is passed in"
</slot>
</body>
</html>

Then use it like

myFile.astro
---
import MainLayout from "../layouts/MainLayout.astro";
---

<MainLayout title="About">
Hello World!
</MainLayout>

Static Site Generation (SSG) vs Server Side Rendering (SSR)

SSG's are lightning fast with pre-build HTML pages. But if you change any part of your site, the entire site has to be re-built and re-deployed. This is not good for sites that need dynamically generated info.

SSR's generate on-demand HTML. This responds to data changes, but you don't get the speed benfits of pre-generated HTML.

Astro's hybrid approach allows you to select which you want for each page individually

SSG Page Examples

  • Homepage
  • Blog Pages

SSR Page Examples

  • Store pages
  • Adding a public API to your site
  • Large sites with hundreds of routes generated by getStaticPaths
    • Build times improve up to 30% by switching dynamic routes to SSR

Astro Islands

Astro islands extract the UI into smaller, isolated components. Unused javascript is replace with lightweight HTML for faster loads and time-to-interactive (TTI). The astro core concept docs on this can be found here.

You can define which parts of your website need javascript, and which do not. Any javascript in frontmatter will be run server side or at build time. Any javascript within <script> tags will run client side. You can use <script></script> tags in your .astro files. You can also use client:* directives to make componente interactive (hydrated). Example: <Button client:load /> where Button is a jsx component with state.

You can also "lazy-load" them, which means components don't hydrate until they scroll into view. This allows the HTML to be loaded fast so the user can see things quickly, and then become interactive once the JS can finish loading.

note

Hydration is the process where client-side JS converts to a static HTML page.

tip

Available client directives and examples can be found here.

Swiper Example

This uses react for the swiper. See my code here.

Astro Integrations

Astro has many integrations, which you can search through on their integrations page. Supported features you can add with npx astro add, other ones you use the usual npm install. Some useful ones I have noted below.

  • Tailwind - install with npx astro add tailwind and it auto-configures for you
  • React - install with npx astro add react and it auto-configures for you
  • Netlify
  • astro-netlify-cms - open source, git based CMS that integrates with Netlify and Jamstack architecture
  • Prism - syntax highlighting for code blocks
  • Sitemap - generates an xml sitemap, you need this
  • MDX - use React components in markdown files
  • robots-txt - generates and syncs the robots.txt file with astro config
  • astro-icon - a ton of icons from various sources that inline as SVGs
  • astro-embed-youtube
  • astro-google-fonts-optimizer
  • Partytown - Lazy-loading library to make sure third-party scripts (like analytics or ads) don't slow down your site. Use this!
  • RSS - Astro RSS integration
  • Analytics - snippets injection for popular web analytics tools
  • Astro-seo - helper for adding useful SEO info to your pages
  • Odyssey Theme - modern theme/starter for business or startup's marketing website

UI Frameworks

Astro only supports some frameworks due to how it manages javascript. Some that it supports include Tailwind (first class support!), Bootstrap, Vanilla Extract.

info

Within Tailwind, there are a ton of component frameworks you can use. Some of those are Daisy UI, Tailblocks, Tailwind UI, and Flowbite.

Some that Astro does NOT support include Material UI, and Mantine. This is because they rely on CSS in Javascript.

CSS Styling

You can inline style like <p style="classnames">Text</p> like normal HTML. You can also do <p style={{backgroundColor:"red"}}>Text</p>.

Can also add style tag directly in component. These only have local scope! The below example only affects the h1's of this page.

---
import MainLayout from "../layouts/MainLayout.astro";
---

<MainLayout title="About">
<h1>About page!</h1>
</MainLayout>

<style>
h1 {
background-color: gold;
}
</style>

If you want the styles to apply for all, see the below.

---
import MainLayout from "../layouts/MainLayout.astro";
---

<MainLayout title="About">
<h1>About page!</h1>
</MainLayout>

<style is:global>
h1 {
background-color: gold;
}
</style>

Other Languages

You can also use other languages, like scss. This will require other dependencies, like npm i -D sass.

<style lang="scss">
h1{
background-color: gold;

&:hover {
background-color: blue;
}
}
</style>

Global CSS

For using global css, create the css file under src, like src/styles/global.css. Import it in whatever files you want to use it in (can do your template), in frontmatter.

---
import "../styles/global.css";
const { title } = Astro.props;
---

Post CSS

Recommend using Post CSS if not using Tailwind npm i postcss postcss-preset-env postcss-preset-env. You will need to add file postcss.config.cjs.

module.exports = {
plugins: [
require("postcss-preset-env")({
stage: 0,
}),
],
};

Then in package.json you need

"browserslist": [
"defaults"
],

Passing Classes to Components

---
export interface Props {
text: string; // button text
href: string; // href
hidey: boolean; // if {true}, then button will be hidden on small devices
}

const { text, href, hidey } = Astro.props;
---

<a
href={href}
class:list={[
"p-3 px-6 pt-2 text-white bg-brightRed rounded-full baseline hover:bg-brightRedLight",
{ "hidden md:block": hidey, block: !hidey },
]}>{text}</a
>

Use it like

---
import ButtonPrimary from "../ButtonPrimary/ButtonPrimary.astro";
---

<ButtonPrimary text="Get Started" href="" hidey={true} />

Icons

Use the package astro-icons with npm i astro-icon.

Their icon list can be found here.

tip

I have had issues with certain icon sets. Some that have NOT worked for me include "material-symbols" and "ri".

Some that HAVE worked for me are "mdi", "iconoir", "tabler".

Extras

AWS Adapter for Astro

Can use SST to build full-stack apps on AWS. Works with Astro, Next.js, Remix, and Solid and allows you to add backend features like a database, GraphQL API, Auth, Cron jobs, and any other AWS service.

Build an Astro blog

Great youtube video I followed while learning the basics of Astro.

Serverless Functions with Astro

Astro and Netlify functions